﻿//
// Created by Administrator on 2022/6/15.
//

//
// Created by gogoqiu on 2022/1/11.
//

#include "MainDialog.h"
#include "wx/wx.h"
#include "wx/confbase.h"
#include "wx/stdpaths.h"
#include "wx/sysopt.h"
#include <wx/fs_zip.h> // ZIP filesystem support
#include <wx/tipdlg.h>
#include <wx/cshelp.h>
#include <wx/image.h>
#include <cstdio>
#include <stdlib.h>
#include <cstring>
#include "action_event.h"
//#include "libssh2.h"
//#include <netdb.h>
//#include <arpa/inet.h>
#include "ids.h"
#include "../../repLib/src/func.h"
#include "MainApp.h"

using namespace std;
#define TIMER_ID 1000

extern string remote_mysql_ip;
extern int  remote_mysql_port;
extern string mysql_user;
extern string mysql_password;
extern string mysql_database;

class PostFileWorker: public wxThread
{
    MainDialog* dialog;

    int run_session(){
        RepSession repSession;
        //pack all info to the run class
        repSession.init( dialog->m_filePicker1->GetFileName(),
                         dialog, dialog->conn_ptr, dialog->should_delete_file );
        repSession.postFile();
        return 0;
    }
public:
    explicit PostFileWorker ( MainDialog* dialog ){
        this->dialog = dialog;
    }
    void * Entry() override{
        run_session();
        return nullptr;
    }
};

//
BEGIN_EVENT_TABLE ( MainDialog, wxFrame )
                EVT_MENU ( ACTION_EVENT, MainDialog::OnActionEvent )
                EVT_BUTTON ( ID_BUTTON_START_POST, MainDialog::OnStartPost )
                EVT_FILEPICKER_CHANGED( ID_FILE_PICKER, MainDialog::OnFilePickerChange )
                //wxEventTableEntry(wxEVT_CHECKBOX, ID_DELETE_FILE, wxID_ANY, wxNewEventTableFunctor(wxEVT_CHECKBOX, wxEventFunctionCast(
                //        static_cast<wxCommandEventFunction>(&MainDialog::OnCBFileDelete))), 0),
                EVT_CHECKBOX( ID_DELETE_FILE, MainDialog::OnCBFileDelete )
                EVT_TIMER(TIMER_ID, MainDialog::OnTimer)
END_EVENT_TABLE()

void MainDialog::buildMenu()
{
    auto *menuFile = new wxMenu;
    //
    menuFile->Append ( ID_Hello, "&Hello...\tCtrl-H",
                       "Help string shown in status bar for this menu item" );
    menuFile->AppendSeparator();
    menuFile->Append ( wxID_EXIT );

    auto *menuHelp = new wxMenu;
    menuHelp->Append ( wxID_ABOUT );

    auto *menuBar = new wxMenuBar;
    menuBar->Append ( menuFile, "&File" );
    menuBar->Append ( menuHelp, "&Help" );
    SetMenuBar ( menuBar );

    //
    Bind ( wxEVT_MENU, &MainDialog::OnHello, this, ID_Hello );
    Bind ( wxEVT_MENU, &MainDialog::OnAbout, this, wxID_ABOUT );
    Bind ( wxEVT_MENU, &MainDialog::OnExit, this, wxID_EXIT );
}

/*
 * 建立右击菜单，传送文件
 * */
MainDialog::MainDialog ( wxWindow *parent )
        : wxFrame ( parent, ID_FRAME_REPOSITORY,
                "Transfer", wxDefaultPosition, wxDefaultSize,
                    wxDEFAULT_FRAME_STYLE ^ wxMAXIMIZE_BOX ^ wxRESIZE_BORDER )
{
    buildMenu();
    CreateStatusBar();
    SetLabel("Transfer");
    //SetStatusText ( "Welcome to wxWidgets!" );

    SetClientSize ( wxSize ( 350, 500 ) );

    dialogRootBoxSizer = new wxBoxSizer ( wxVERTICAL );

    m_gauge1 = new wxGauge( this, wxID_ANY, 101,
            wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL );
    m_gauge1->SetValue( 0 );

    dialogRootBoxSizer->Add( m_gauge1, 0, wxALL | wxEXPAND, 5 );

    //test_delay_button = new wxButton( this, ID_BUTTON_DELAY, "Delay");
    //dialogRootBoxSizer->Add( test_delay_button, 0, wxALL, 5 );

    m_filePicker1 = new wxFilePickerCtrl ( this, ID_FILE_PICKER,
            wxEmptyString, wxT ( "Select a file" ), wxT ( "*.*" ),
            wxDefaultPosition, wxDefaultSize,
            wxFLP_DEFAULT_STYLE );
    dialogRootBoxSizer->Add ( m_filePicker1, 0, wxALL | wxEXPAND, 5 );

    start_post_button = new wxButton ( this,
            ID_BUTTON_START_POST, "启动传送" );
    auto *rowBox = new wxBoxSizer( wxHORIZONTAL );
    cb_isDelete = new wxCheckBox( this, ID_DELETE_FILE,
            wxT("Delete File After Finishing?"),
                                  wxDefaultPosition, wxDefaultSize, 0 );
    rowBox->Add( cb_isDelete );
    rowBox->Add( start_post_button );

    dialogRootBoxSizer->Add ( rowBox, 0, wxALL, 5 );

    wxSize size ( 300, 500 );
    m_logBox = new wxTextCtrl ( this, wxID_ANY, wxEmptyString,
            wxDefaultPosition, size, wxTE_MULTILINE );
    dialogRootBoxSizer->Add ( m_logBox,  0, wxALL | wxEXPAND, 5  );

    this->SetSizer ( dialogRootBoxSizer );

    //form
    //path, button_start( pause ), log
    //选择文件
    //拖拽

    //Bind(wxEVT_CLOSE_WINDOW,wxCloseEventHandler(MainDialog::OnClose),this);
    conn_ptr = mysql_init(nullptr);
    if (!conn_ptr) {
        //0
        //printf("mysql_init failed\n");
        //fail
        addLog("mysql初始化失败");
    }
    //?
    conn_ptr = mysql_real_connect( conn_ptr, remote_mysql_ip.c_str(),
                                   mysql_user.c_str(), mysql_password.c_str(),
                                   mysql_database.c_str(), remote_mysql_port, nullptr, 0);
    if (!conn_ptr) {
        addLog("mysql连接失败");
    }else
        addLog("mysql已连接");
    //item = 0;
    should_delete_file = false;
    m_timer = new wxTimer(this, TIMER_ID);
    //启动定时器，参数是定时的时间间隔
    m_timer->Start(1000*60*10);
    //
    if ( wxGetApp().getFileName()!= nullptr ){
        wxFileName *fileName = wxGetApp().getFileName();
        if( fileName->FileExists() ) {
            m_filePicker1->SetFileName(*fileName);
            cb_isDelete->SetValue(wxGetApp().getDeleted());
            should_delete_file = wxGetApp().getDeleted();
            wxCommandEvent event1;
            OnStartPost(event1);
        }else{
            wxString tmp;
            tmp.sprintf("文件不存在: %s\n", fileName->GetFullPath() );
            addLog( tmp );
        }
    }
}

void MainDialog::OnTimer( wxTimerEvent& event ){
    int retVal = mysql_query(conn_ptr, "SET NAMES UTF8");
    wxDateTime dateTime = wxDateTime::Now();
    wxString tmp;
    wxString t = dateTime.FormatTime();
    if (retVal != 0) {
        tmp.sprintf( wxT("%s: %s"), t, mysql_error(conn_ptr) );
        //addLog( mysql_error(conn_ptr) );
    }else{
        tmp.sprintf( wxT("%s: %s"), t, wxT("延续MySql连接") );
    }
    addLog( tmp );
}

/*
 * background service
 * onInit的时候启动，关闭时关闭。ui上可以看见状态
 */
void MainDialog::request()
{
    //this->SetSizer(dialogRootBoxSizer);
    //Layout();
}

void MainDialog::OnClose ( wxCloseEvent&  event )
{
    this->Show ( false );
}

MainDialog::~MainDialog()
{
    for ( int i = 0; i < panels.size(); i++ ) {
        //panels.at(i)->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( PreferencesFrame::OnClickItem ), NULL, this );
    }
    m_timer->Stop();
    if( conn_ptr )
        mysql_close(conn_ptr);
}

void MainDialog::OnExit ( wxCommandEvent& event )
{
    Close ( true );
}

void MainDialog::OnAbout ( wxCommandEvent& event )
{
    wxMessageBox ( "This is a wxWidgets Hello World example",
                   "About Hello World", wxOK | wxICON_INFORMATION );
}

void MainDialog::OnHello ( wxCommandEvent& event )
{
    wxLogMessage ( "Hello world from wxWidgets!" );
}

void MainDialog::OnClickItem ( wxMouseEvent &event )
{

}

void MainDialog::OnActionEvent ( wxCommandEvent &event )
{
    const int token = event.GetInt();
    const long liType = event.GetExtraLong();
    switch ( token ) {
        case TOKEN_INFO:
            break;
        case TOKEN_ERROR:
            break;
        case TOKEN_ACTION_START:
            break;
        case TOKEN_ACTION_END:
            this->m_filePicker1->Enable();
            break;
        case TOKEN_DELAY_TEST: {
            int value = m_gauge1->GetValue();
            m_gauge1->SetValue(value + 1);
            break;
        }
        case TOKEN_LOG:{
            wxString log = event.GetString();
            addLog( log );
            break;
        }
        case TOKEN_SCP_PERCENT:{
            auto *value = (int*)event.GetClientData();
            printf( "%d\n", *value );
            m_gauge1->SetValue(*value);
            delete value;
            break;
        }
    }
}

//start button callback
void MainDialog::OnStartPost(wxCommandEvent &event) {
    wxString path = this->m_filePicker1->GetPath();
    if( path.IsSameAs(_T("")))
        return;
    this->start_post_button->Disable();
    this->m_filePicker1->Disable();
    //
    postFileWorker = new PostFileWorker ( this );
    postFileWorker->Run();
}

void MainDialog::addEventLog( const wxString& log ){
    wxString tmp = log;
    if( !log.EndsWith("\n"))
        tmp = tmp +  _T("\n") ;
    ActionEvent event( this, TOKEN_LOG, tmp );
    event.Post();
}

void MainDialog::addLog( const wxString& log ){
    wxString tmp = log;
    if( !log.EndsWith("\n"))
        tmp = tmp +  _T("\n") ;
    this->m_logBox->AppendText( tmp );
}

void MainDialog::OnFilePickerChange(wxFileDirPickerEvent &event) {
    this->start_post_button->Enable();
}

void MainDialog::OnCBFileDelete(wxCommandEvent &event) {
    should_delete_file = cb_isDelete->GetValue();
}

//程序A和程序B，其中程序A向程序B发送自定义消息，在Win7、XP上都没有问题，但是在Win8、Win10中有些时候无法收到消息，导致调用失败。
//https://blog.csdn.net/u011677067/article/details/52494184
WXLRESULT MainDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) {
    //const UINT m_myMsg = RegisterWindowMessage(_T("MY_MESSAGE"));
    //将m_myMsg消息加入白名单，不会因为权限被阻止
    //ChangeWindowMessageFilter(m_myMsg, MSGFLT_ADD);
    switch( message )
    {
        case WM_COPYDATA:{
            auto *cds = (COPYDATASTRUCT*)lParam;
            //wxString path( *tmp );
            //int *z = (int*)wParam;
            auto * buf = ( wchar_t * )cds->lpData;
            int len = cds->cbData / sizeof( wchar_t );
            auto* buff = new wchar_t[len + 1];
            memcpy_s(buff, sizeof(wchar_t) * (len + 1), buf,
                     sizeof(wchar_t) * len);
            buff[len] = 0;
            //wxMessageBox( buff , wxT("消息"));
            //auto * buf = ( wxString * )cds->lpData;
            wxString path(buff);
            //path.Replace("\\", "\\\\");
            wxFileName fileName( path );
            if( fileName.FileExists()  ){
                if( cds->dwData==1 ){
                    should_delete_file = true;
                    cb_isDelete->SetValue( true );
                }else{
                    should_delete_file = false;
                    cb_isDelete->SetValue( false );
                }
                addLog( path );
                m_filePicker1->SetFileName( fileName );
                wxCommandEvent event;
                OnStartPost( event );
            }else{
                wxString tmp;
                tmp.sprintf( wxT("文件不存在: %s"), path );
                addLog( tmp );
            }
            //wxMessageBox( *buf , wxT("消息"));
            break;
        }
        default:
            break;
    }
    /*
    if( message == m_myMsg ){
            //auto *s = (wxString*)lParam;
            char *msg = (char*)lParam;
            //wxString path( *tmp );
            int *z = (int*)wParam;
            wxMessageBox( "123" , wxT("消息"));
        //    break;
    }*/
    return wxFrame::MSWWindowProc(message, wParam, lParam);
}


//watching
//电驴版
//torrent版
//额外信息
